home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The PC-SIG Library 10
/
The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso
/
PC_SIGCD
/
22
/
4
/
DISK2247.ZIP
/
CBASE101.ZIP
/
BLKIO112.ZIP
/
LOCKB.C
< prev
next >
Wrap
Text File
|
1990-06-20
|
5KB
|
219 lines
/* Copyright (c) 1989 Citadel */
/* All Rights Reserved */
/* #ident "@(#)lockb.c 1.4 - 90/06/20" */
/* ansi headers */
#include <errno.h>
/*#include <stddef.h>*/
/* local headers */
#include "blkio_.h"
/* function declarations */
#if HOST == UNIX
#include <fcntl.h>
#ifdef AC_PROTO
int fcntl(int fd, int cmd, ...);
#else
int fcntl();
#endif
#elif HOST == MS_DOS
#endif
/*man---------------------------------------------------------------------------
NAME
lockb - block file record locking
SYNOPSIS
#include <blkio.h>
int lockb(bp, ltype, start, len)
BLKFILE *bp;
int ltype;
bpos_t start;
bpos_t len;
DESCRIPTION
The lockb function will allow segments of a block file to be
locked. bp is the BLKFILE pointer for the file to be locked.
ltype indicates the target status of the lock. The lock types
available are:
B_UNLCK unlock block file segment
B_RDLCK lock block file segment for reading
B_WRLCK lock block file segment for reading and writing
B_RDLKW lock block file segment for reading (wait)
B_WRLKW lock block file segment for reading and writing (wait)
For the lock types which wait, lockb will not return until the
lock is available. For the lock types which do not wait, if the
lock is unavailable because of a lock held by another process a
value of -1 is returned and errno set to EAGAIN.
start is the first block to lock. len is the number of
contiguous blocks including and following block start to be
locked or unlocked. A lock may be set to extend to the end of
the file by setting len to zero.
The buffers are flushed before unlocking.
lockb will fail if one or more of the following is true:
[EAGAIN] ltype is B_RDLCK and the file segment to be locked
is already write locked by another process, or
ltype is B_WRLCK and the file segment to be locked
is already read or write locked by another
process.
[EINVAL] bp is is not a valid BLKFILE pointer.
[EINVAL] ltype is not one of the valid lock types.
[BENOPEN] bp is not open.
[BENOPEN] ltype is B_RDLCK or B_RDLKW and bp is not opened
for reading or ltype is B_WRLCK or B_WRLKW and bp
is not open for writing.
DIAGNOSTICS
Upon successful completion, a value of 0 is returned. Otherwise,
a value of -1 is returned, and errno set to indicate the error.
------------------------------------------------------------------------------*/
int lockb(bp, ltype, start, len)
BLKFILE *bp;
int ltype;
bpos_t start;
bpos_t len;
{
#if HOST == UNIX
int cmd = 0;
struct flock lck;
#elif HOST == MS_DOS
/* There is no standard mechanism for file locking in MS-DOS. If
using a multiuser version of MS_DOS (e.g., Digital Research
Concurrent DOS) or networking extensions which provide file
locking, then the file locking calls should be added to this file.
No other file needs to be modified to use file locking in blkio. */
#endif
/* validate arguments */
if (!b_valid(bp)) {
errno = EINVAL;
return -1;
}
/* check if not open */
if (!(bp->flags & BIOOPEN)) {
errno = BENOPEN;
return -1;
}
/* set lock flags */
switch (ltype) {
case B_RDLCK:
if (!(bp->flags & BIOREAD)) {
errno = BENOPEN;
return -1;
}
#if HOST == UNIX
cmd = F_SETLK;
lck.l_type = F_RDLCK;
#elif HOST == MS_DOS
#endif
break;
case B_RDLKW:
if (!(bp->flags & BIOREAD)) {
errno = BENOPEN;
return -1;
}
#if HOST == UNIX
cmd = F_SETLKW;
lck.l_type = F_RDLCK;
#elif HOST == MS_DOS
#endif
break;
case B_WRLCK:
if (!(bp->flags & BIOWRITE)) {
errno = BENOPEN;
return -1;
}
#if HOST == UNIX
cmd = F_SETLK;
lck.l_type = F_WRLCK;
#elif HOST == MS_DOS
#endif
break;
case B_WRLKW:
if (!(bp->flags & BIOWRITE)) {
errno = BENOPEN;
return -1;
}
#if HOST == UNIX
cmd = F_SETLKW;
lck.l_type = F_WRLCK;
#elif HOST == MS_DOS
#endif
break;
case B_UNLCK:
/* flush buffers */
if (bflush(bp) == -1) {
BEPRINT;
return -1;
}
#if HOST == UNIX
cmd = F_SETLK;
lck.l_type = F_UNLCK;
#elif HOST == MS_DOS
#endif
break;
default:
errno = EINVAL;
return -1;
break;
}
/* lock block file */
#if HOST == UNIX
if (start == 0) {
lck.l_whence = 0;
if (len == 0) {
lck.l_len = 0;
} else {
lck.l_len = bp->hdrsize + (len - 1) * bp->blksize;
}
} else {
lck.l_whence = bp->hdrsize + (start - 1) * bp->blksize;
if (len == 0) {
lck.l_len = 0;
} else {
lck.l_len = len * bp->blksize;
}
}
lck.l_start = 0;
lck.l_sysid = 0;
lck.l_pid = 0;
if (fcntl(bp->fd.ifd, cmd, &lck) == -1) {
/* new versions of fcntl will use EAGAIN */
if (errno == EACCES) errno = EAGAIN;
if (errno != EAGAIN) BEPRINT;
return -1;
}
#elif HOST == MS_DOS
#endif
/* if locking, load endblk */
if (ltype != B_UNLCK) {
if (b_uendblk(bp, &bp->endblk) == -1) {
BEPRINT;
return -1;
}
}
errno = 0;
return 0;
}